import uuid

from django.core.paginator import Paginator
from rest_framework.decorators import api_view
from django.core.files.temp import NamedTemporaryFile
import docker

from image.models import HarborImage
from image.request_serializer import HarborUploadSerializer, PageSerializer, GetRobotAccountSerializer
from image.serializer import HarborImageSerializer, SimpleHarborImageSerializer
from utils.base_response import BaseResponse
from utils.base_response_code import BaseResponseCode
from AIMall.settings import CONFIG
from utils.harbor_client import HarborClient
from utils.page_data import page_data
from utils.validate_request import validate_request

harbor_config = CONFIG['HARBOR']
harbor_client = HarborClient(harbor_config['api_base_url'], harbor_config['api_authorization'], verify_ssl=False)


@api_view(['GET'])
def hello(request):
    return BaseResponse(BaseResponseCode.SUCCESS, "Hello, world!", {"hello": "world"})


@api_view(['POST'])
def check_health(request):
    client = docker.from_env()
    images = client.images.list()
    harbor_health_response = harbor_client.check_health()
    return BaseResponse(BaseResponseCode.SUCCESS, "Check if Docker and Harbor are healthy",
                        {
                            "docker images count": len(images),
                            "harbor health": harbor_health_response.json(),
                        })


@api_view(['POST'])
@validate_request(HarborUploadSerializer)
def harbor_upload(request, serializer):
    file = request.FILES.get('image')

    with NamedTemporaryFile() as tmp_file:
        for chunk in file.chunks():
            tmp_file.write(chunk)
        tmp_file_path = tmp_file.name

        client = docker.from_env()
        with open(tmp_file_path, 'rb') as f:
            img = client.images.load(f.read())[0]
        client.login(registry=harbor_config['registry'],
                     username=harbor_config['username'],
                     password=harbor_config['password'])
        origin_image_name_tag = img.tags[0] if img.tags else 'unknown:latest'
        origin_image_name, origin_image_tag = origin_image_name_tag.split(':')

        project_name = str(uuid.uuid4())[:8]
        response = harbor_client.create_project(project_name, False)
        if response.status_code != 201:
            return BaseResponse(BaseResponseCode.HARBOR_API_CREATE_PROJECT_FAILED,
                                "create project failed",
                                response.json())

        repository = f"{harbor_config['registry']}/{project_name}/{origin_image_name}"
        img.tag(repository=repository, tag=origin_image_tag)
        img_url = f"{repository}:{origin_image_tag}"
        push_result = client.images.push(img_url)
        if 'errorDetail' in push_result:
            return BaseResponse(BaseResponseCode.DOCKER_PUSH_FAILED, "harbor push failed", {'push_result': push_result})

        new_harbor_image = HarborImage.objects.create(url=img_url, project_name=project_name,
                                                      **serializer.validated_data)
        return BaseResponse(BaseResponseCode.SUCCESS, "upload success", HarborImageSerializer(new_harbor_image).data)


@api_view(['GET'])
@validate_request(PageSerializer)
def get_harbor_images(request, serializer):
    images = HarborImage.objects.all().order_by('-uploaded_at')
    paginator = Paginator(images, serializer.validated_data['page_size'])

    return BaseResponse(BaseResponseCode.SUCCESS, "success",
                        page_data(paginator, serializer.validated_data['page_num'], SimpleHarborImageSerializer))


@api_view(['POST'])
@validate_request(GetRobotAccountSerializer)
def get_robot_account(request, serializer):
    image = HarborImage.objects.filter(url=serializer.validated_data['uri']).first()
    if image is None:
        return BaseResponse(BaseResponseCode.DATA_NOT_FOUND, "uri image not found", None)
    response = harbor_client.create_robot_account(image.project_name)
    return BaseResponse(BaseResponseCode.SUCCESS, "success", response.json())
